#include<stdio.h>
#include<stdlib.h>
#include<sys/ipc.h>
#include<sys/shm.h>
#include<string.h>
#include<time.h>
#include<sys/sem.h>

typedef struct _test{
	int a_val;
	int b_val;
	int a_flag;
	int b_flag;
	int game_no;
	int stage;
}test;

void sem_p();
void sem_v();
void set_sem();
void del_sem();
int sem_id;

union semun{
	int val;
	struct semid_ds *buf;
	unsigned short *arry;
};

int pk[3][3] = {0,-1,1,1,0,-1,-1,1,0};
int other[3][3] = {0,2,1,1,0,2,2,1,0};
int you;
int arr[3];

int main(){
	srand((int)time(0));
	int shmid;
	test* shm;
	
	shmid = shmget((key_t)1236,sizeof(test),0666);	
	if(shmid == -1){
		printf("shmget failed\n");
		exit(EXIT_FAILURE);
	}
	printf("%d",shmid);

	shm = shmat(shmid,0,0);
	if (shm == (void*)-1){
		printf("shmat failed\n");
		exit(EXIT_FAILURE);
	}
	printf("\nMemory attached at %X\n",(int)shm);
	
	sem_id = semget((key_t)3000,1,0666|IPC_CREAT);

	int no=0;
	while(1){
		sem_p();
		if(shm->game_no==-1){
			sem_v();
			break;
		}
		if (shm->stage==0){
			if(no!=shm->game_no){
				no = shm->game_no;
				printf("-------------------\n");
				printf("game_no:%d\n",no);
			}
			if(shm->b_flag==0){
				shm->b_flag=1;
				shm->b_val = rand()%3;
				printf("you:%d\n",shm->b_val);
				you = shm->b_val;
			}
		}
		else if(shm->stage==1){
		
		}
		else if(shm->stage==2){
			if(shm->b_flag==0){
				shm->b_flag=1;
				int val=shm->b_val;
				printf("other:%d\n",other[you][(val==-1)?2:val]);
				if(val==0) {arr[0]++; printf("draw!\n");}
				if(val==1) {arr[1]++; printf("you win!\n");}
				if(val==-1){arr[2]++; printf("you lost!\n");}
				printf("-------------------\n");
			}
		}
		sem_v();
	}
	
	printf("draw:%d\nwin:%d\nlost:%d\n",arr[0],arr[1],arr[2]);	

	shmdt(shm);

}
void set_sem(){
	union semun sem_union;
	sem_union.val=1;
	semctl(sem_id,0,SETVAL,sem_union);
}

void del_sem(){
	union semun sem_union;
	semctl(sem_id,0,IPC_RMID,sem_union);
}

void sem_p(){
	struct sembuf sem_b;
	sem_b.sem_num = 0;
	sem_b.sem_op = -1;
	sem_b.sem_flg = SEM_UNDO;
	semop(sem_id,&sem_b,1);
}

void sem_v(){
	struct sembuf sem_b;
	sem_b.sem_num = 0;
	sem_b.sem_op = 1;
	sem_b.sem_flg = SEM_UNDO;
	semop(sem_id,&sem_b,1);
}
